var blockCalendar = new function() {
    const BKGROUND_FILE_NAMES = ["chrome://viecalendar/skin/images/calendar-bg1.png", "chrome://viecalendar/skin/images/calendar-bg2.png"];
    const PAPER_COLORS = ["#124B90", "#C60B16"];
    const ANIMAL_FILE_NAMES = ["chrome://viecalendar/skin/images/12animals/rat.png", "chrome://viecalendar/skin/images/12animals/buffalo.png", "chrome://viecalendar/skin/images/12animals/tiger.png", 
                             "chrome://viecalendar/skin/images/12animals/rabbit.png", "chrome://viecalendar/skin/images/12animals/dragon.png", "chrome://viecalendar/skin/images/12animals/snake.png",
                             "chrome://viecalendar/skin/images/12animals/horse.png", "chrome://viecalendar/skin/images/12animals/goat.png", "chrome://viecalendar/skin/images/12animals/monkey.png",
                             "chrome://viecalendar/skin/images/12animals/rooster.png", "chrome://viecalendar/skin/images/12animals/dog.png", "chrome://viecalendar/skin/images/12animals/pig.png"];
                             
    const CLEAR = " (Đ)";
    const NOT_CLEAR = " (T)";
    const LEAP = "(N)";
    
    var calendarPaperControl;
    var solarMonthViNameControl;
    var solarMonthEnNameControl;
    var solarYearControl;
    var solarDayControl;
    var eventControl;
    var weekdayViNameControl;
    var weekdayEnNameControl;
    var lunarYearNameControl;
    var lunarMonthViNameControl;
    var lunarMonthNameControl;
    var lunarDayNameControl;
    var lunarStartHourNameControl;
    var lunarDayControl;
    var lunarAnimalControl;
    var solarTeamControl;
    var zodiacHoursControl;
    var datepicker;
    
    var date;
    var vieCalendar;
    
    this.initialize = function() {
        calendarPaperControl        = document.getElementById("calendar-paper");
        solarMonthViNameControl     = document.getElementById("solar-month-vi-name");
        solarMonthEnNameControl     = document.getElementById("solar-month-en-name");
        solarYearControl            = document.getElementById("solar-year");
        solarDayControl             = document.getElementById("solar-day");
        eventControl                = document.getElementById("event");
        weekdayViNameControl        = document.getElementById("weekday-vi-name");
        weekdayEnNameControl        = document.getElementById("weekday-en-name");
        lunarYearNameControl        = document.getElementById("lunar-year-name");
        lunarMonthViNameControl     = document.getElementById("lunar-month-vi-name");
        lunarMonthNameControl       = document.getElementById("lunar-month-name");
        lunarDayNameControl         = document.getElementById("lunar-day-name");
        lunarStartHourNameControl   = document.getElementById("lunar-start-hour-name");
        lunarDayControl             = document.getElementById("lunar-day"); 
        lunarAnimalControl          = document.getElementById("lunar-animal");
        solarTeamControl            = document.getElementById("solar-term");
        zodiacHoursControl          = document.getElementById("zodiac-hours");
        datepicker                  = document.getElementById("datepicker");
        
        date = new Date();
        vieCalendar = new VieCalendar(date);
        
        updateCalendar();
    }
    this.selectPrevDay = function() {
        date.setDate(date.getDate() - 1);
        updateCalendar();
    }
    this.selectNextDay = function() {
        date.setDate(date.getDate() + 1);
        updateCalendar();
    }
    this.selectToday = function(event) {
        if(event.target.tagName == "command") {
            date = new Date();
            updateCalendar();
        }
    }
    this.printDate = function() {
        alert(getString("message.feature-not-available"));
    }
    this.insertEvent = function() {
        var event = new Event();
        event.day = vieCalendar.getSolarDay();
        event.month = vieCalendar.getSolarMonth();
        event.year = vieCalendar.getSolarYear();
        event.type = SOLAR;
        
        window.openDialog("event-editor.xul", "event-editor", "modal,centerscreen", vieCalendar, event);
        updateCalendar();
    };
    this.modifyEvent = function(id) {
        var storage = new Storage(getDbFile());
        var event = storage.findEventById(id);
        
        window.openDialog("event-editor.xul", "event-editor", "modal,centerscreen", vieCalendar, event);
        updateCalendar();
    };
    this.deleteEvent = function(id) {
        var ok = confirm(getString("event.delete-confirm"));
        if(ok) {
            var storage = new Storage(getDbFile());
            storage.deleteEvent(id);
            updateCalendar();
        }
    };
    this.chooseDate = function() {
        date = datepicker.dateValue;
        updateCalendar();
        datepicker.parentNode.hidePopup();
    }
    this.viewTableCalendar = function() {
        alert(getString("message.feature-not-available"));
    }
    this.manageEvents = function() {
        alert(getString("message.feature-not-available"));
    }
    this.getCalendarInfo = function() {
        window.openDialog("viecalendar-info.xul", "viecalendar-info", "modal,centerscreen");
    }
    this.closeApp = function() {
        window.close();
    }
    function updateCalendar() {
        vieCalendar.setSolarDate(date);
        var storage = new Storage(getDbFile());
        var events = storage.findEvents(vieCalendar.getSolarDay(), vieCalendar.getSolarMonth(), vieCalendar.getLunarDay(), vieCalendar.getLunarMonth());
        updateEventsOfDay(events);
        
        solarMonthViNameControl.innerHTML     = vieCalendar.getSolarMonthName("vi").toUpperCase();
        solarMonthEnNameControl.innerHTML     = vieCalendar.getSolarMonthName("en").toUpperCase();
        solarYearControl.innerHTML            = vieCalendar.getSolarYear();
        solarDayControl.innerHTML             = vieCalendar.getSolarDay();
        weekdayViNameControl.innerHTML        = vieCalendar.getWeekDayName("vi").toUpperCase();
        weekdayEnNameControl.innerHTML        = vieCalendar.getWeekDayName("en").toUpperCase();
        lunarYearNameControl.innerHTML        = getString("calendar.year", [vieCalendar.getLunarYearName().toUpperCase()]);
        
        var lunarMonthViName = vieCalendar.getLunarMonthName("vi").toUpperCase();
        if(vieCalendar.isLunarLeapMonth()) {
            lunarMonthViName += LEAP; 
        }
        lunarMonthViName += vieCalendar.isLunarClearMonth()? CLEAR : NOT_CLEAR;
                        
        lunarMonthViNameControl.innerHTML     = lunarMonthViName;
        
        lunarMonthNameControl.innerHTML       = getString("calendar.month", [vieCalendar.getLunarMonthName()]);
        lunarDayNameControl.innerHTML         = getString("calendar.day", [vieCalendar.getLunarDayName()]);
        lunarStartHourNameControl.innerHTML   = getString("calendar.hour", [vieCalendar.getLunarStartHourName()]);
        lunarDayControl.innerHTML             = vieCalendar.getLunarDay();
        lunarAnimalControl.src                = ANIMAL_FILE_NAMES[(vieCalendar.getJuliusDays() + 1) % 12];
        solarTeamControl.innerHTML            = getString("calendar.solar-term", [vieCalendar.getSolarTerm()]);
        zodiacHoursControl.innerHTML          = getString("calendar.zodiac-hours", [vieCalendar.getZodiacHourNames().join(", ")]);
        
        var index = !isSpecialDay(events)? 0 : 1;
        calendarPaperControl.style.color = PAPER_COLORS[index];
        calendarPaperControl.style.backgroundImage = "url(" + BKGROUND_FILE_NAMES[index] + ")";
        weekdayViNameControl.style.backgroundColor = PAPER_COLORS[index];
        weekdayEnNameControl.style.backgroundColor = PAPER_COLORS[index];
        
        datepicker.date = vieCalendar.getSolarDay(); 
        datepicker.month = vieCalendar.getSolarMonth() - 1;
        datepicker.year = vieCalendar.getSolarYear();
    }
    function isSpecialDay(events) {
        var special = false;
        for(i=0; i<events.length; i++) {
            if(events[i].special) {
                special = true;
                break;
            }                
        }
        return (vieCalendar.getWeekDay() == 0 || special);
    }
    function updateEventsOfDay(events) {
        var msg;
        if(events.length > 0) {
            msg = buildEventContent(events[0]);
        } else {
            msg = getString("event.insert-tip", [getString("event.insert-action")]);
        }
        
        eventControl.innerHTML = msg;
    }
    function buildEventContent(event) {
        message = event.title;
        
        var arr = /\$\{(\-?\d+)\}/g(message);
        if(arr) {
            var years = vieCalendar.getSolarYear() - arr[1];
            message = message.replace(/\$\{(\-?\d+)\}/g, years);
        }
        
        var decoder = new TextDecoder();
        message = decoder.decode(message);
        
        message += buildEventActions(event);
        
                
        return message;
    }   
    function buildEventActions(event) {
        var data = "";
        data += getString("event.modify-action", [event.id]);
        data += getString("event.delete-action", [event.id]);
        
        return data;
    }
}